package com.example.consumer.direct;

import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author: dangwen
 * @createDate: 2020/12/6
 * 日志消息消费者，只消费Info日志
 * 日志消息存储在队列：log-info-queue
 * 使用的交换器的名称是：log-ex-direct
 * 交换器的类型是：direct
 * 队列的路由键是: direct-rk-info
 *
 * @RabbitListener: 监听注解，可以描述类型和方法
 *  描述类型：当前类型监听某个队列
 *  描述方法：当前方法监听某个队列
 *  bindings：QueueBinding[]类型，代表这个类型或者方法监听的队列、交换器、路由键的绑定方式
 *      推荐注解在类上，@RabbitHandler注解在方法上，通过参数的重载，来解析不同类型的业务参数，处理不同的业务需求。
 *      1.@RabbitListener：类+方法上(表明监听哪些队列即可)
 *      2.@RabbitHandler: 标在方法上(重载区分不同的消息)
 *
 * @QueueBinding: 定义了多种属性，这里举例其中三个核心属性：
 *  value - 绑定监听的队列是什么
 *  exchange - 队列对应的交换器是什么
 *  key - 队列的路由键是什么
 *
 * @Queue: 描述一个队列
 *  value|name - 队列名称
 *  autoDelete - 是否自动删除，默认为""，如果定义了队列名称，则不自动删除，如果不定义队列名称，则表示自动删除队列.
 *      (不定义队列名称，用的时候还是会随机生成一个队列名称，所以有删除的必要)。
 *
 * @Exchange: 描述一个交换器
 *  value|name - 交换器名称
 *  type - 交换器的类型，可选 direct|fanout|topic, 默认是direct
 *  autoDelete - 是否自动删除，默认为false，表示不自动删除。
 *
 *
 * @Component: mq的@RabbitListener注解，并不能直接被spring，如果想要注入spring容器，需要通过配置类或者组件的方式注入进来。
 */
@RabbitListener(bindings = {
    @QueueBinding(
            value = @Queue(value = "log-info-queue", autoDelete = "false"),
            exchange = @Exchange(value = "log-ex-direct", type = "direct", autoDelete = "false"),
            key = "direct-rk-info"
    )
})
@Component
public class InfoLogConsumer {
    /**
     * 消息消费的方法，当log-info-queue中出现消息。立即消费。msg就是消息内容。
     * 方法名自定义
     * 入参类型自定义
     *
     * @RabbitHandler: 配合类型上的@RabbitListener注解，标记当前方法是一个监听消息队列，消费消息的方法。
     *  如果@RabbitListener注解用来描述方法，则该方法上不需要再添加@RabbitHandler注解
     */
    @RabbitHandler
    public void onMessage(String msg){
        System.out.println("InfoLogConsumer--onMessage方法消费消息:"+msg);
    }

    @RabbitHandler
    public void onMessage(int i){
        System.out.println(i);
    }
}
